use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder,Result,HttpRequest,Error};
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use serde::{Deserialize, Serialize};
use futures::future::{ready, Ready};
use std::collections::HashMap;

use rbatis::crud::{CRUD, CRUDEnable};
use rbatis::plugin::logic_delete::RbatisLogicDeletePlugin;
use rbatis::plugin::page::{Page, PageRequest};
use rbatis::rbatis::Rbatis;
use rbatis::core::Error as rbatis_error;
use rbatis_macro_driver::sql;
use chrono::NaiveDateTime;
use bigdecimal_::BigDecimal;
use rbatis::core::value::DateTimeNow;
use fast_log::filter::{ModuleFilter};
use rbatis::core::db_adapter::DBExecResult;


// impl ResponseError for rbatis_error{
//     fn error_response(&self) -> Response<Body>{

//     }

//     fn status_code(&self) -> StatusCode{

//     }
// }

// use mysql::prelude::*;
// use mysql::*;

// use mysql_async::{prelude::*, Error, Opts, Pool, QueryResult, Result};

// use sqlx::{PgPool, FromRow, Row};

#[get("/")]
async fn hello() -> impl Responder {

    let rbatis =  init_rbatis().await;
    let tx_id = "3";//事务id号
    rbatis.begin(tx_id).await.unwrap();

    let store_list = select_store(&rbatis, &tx_id).await;
    if  let Ok(mut s_list) = store_list{
        for store in &mut s_list{
            match &store.id {
                Some(s_id) => {
                    let ba_list = select_biz_activity_by_store_id(&rbatis, &tx_id, s_id.to_string()).await;
            
                    if let Ok(mut list) = ba_list{
                        store.biz_activity_list = Some(list.clone());
                        println!("store.biz_activity_list = {:?}", store.biz_activity_list);
                        if let Some(sba_list) = &mut store.biz_activity_list{
                            for activity in sba_list{
                                match &activity.id{
                                    Some(a_id) => {
                                        let c_list = query_activity_commodity(&rbatis, &tx_id, a_id.to_string()).await;
                                        if let Ok(l) = c_list{
                                            println!("l = {:?}", l);
                                            activity.commodity_list = Some(l);
                                        }
                                        println!("activity.commodity_list = {:?}", activity.commodity_list);
                                    },
                                    None =>{

                                    }
                                }
                            }
                        }
                    }
                },
                None =>{

                }
            }
        }

        rbatis.commit(tx_id).await.unwrap();

        HttpResponse::Ok().json(
            s_list
        )
    }else{
        let mut map :HashMap<String,  Option<String>> = HashMap::new();
        map.insert("code".to_string(),  Some("400".to_string()));
        map.insert("data".to_string(), None);
        map.insert("message".to_string(), Some("查询失败".to_string()));
        HttpResponse::Ok().json(map)
    }

    // let c_list = query_activity_commodity(&rbatis, "3", "1").await;

    // let s_c_list = query_store_activity_commodity(&rbatis, "3", "223", "1774636").await;

    // rbatis.commit(tx_id).await.unwrap();
    // println!("c_list = {:?}", c_list);
    // println!("s_c_list = {:?}", s_c_list);

    // HttpResponse::Ok().body("Hello world!")

    // HttpResponse::Ok().json(
    //     c_list
    // )
}

#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
    // HttpResponse::Ok().body(req_body)

    let rbatis =  init_rbatis().await;
    let tx_id = "2";//事务id号

    rbatis.begin(tx_id).await.unwrap();

    let b = select(&rbatis, tx_id, "178").await;

    rbatis.commit(tx_id).await.unwrap();
    println!("b = {:?}", b);

    // match b{
    //     Ok(result) =>{
    //         HttpResponse::Ok().json( result)
    //     }
    // }

    HttpResponse::Ok().json(
        Info{
            userid: 114234,
            username: String::from("张一鸣"),
            age: 35,
            sex: String::from("男"),
        }
    )

}

async fn manual_hello() -> impl Responder {
    // HttpResponse::Ok().body("Hey there!")

    let map = update_store().await;
    HttpResponse::Ok().json(map)
}

#[post("/delete")]
async fn delete() -> impl Responder {

    let map = delete_store().await;
    HttpResponse::Ok().json(map)
}

/// {friend} - deserializes to a String
#[get("/users/{user_id}/{friend}")] // <- define path parameters
async fn index(web::Path((user_id, friend)): web::Path<(u32, String)>) -> Result<String> {
    println!("Welcome {}, user_id {}!", friend, user_id);
    Ok(format!("Welcome {}, user_id {}!", friend, user_id))
}

#[derive(Serialize, Deserialize)]
struct Info {
    userid: u64,
    username: String,
    age: u8,
    sex: String
}

/// deserialize `Info` from request's body
#[post("/info")]
async fn info(info: web::Json<Info>) -> Result<String> {
    println!("username{}, userid{}, age{}, sex{}!", info.username, info.userid,  info.age, info.sex);
    Ok(format!("Welcome {}!", info.username))
}

#[post("/form")]
async fn form(form: web::Form<Info>) -> Result<String> {
    println!("username{}, userid{}, age{}, sex{}!", form.username, form.userid,  form.age, form.sex);
    Ok(format!("Welcome {}!", form.username))
}

// url 参数解析
#[get("/url")]
async fn url(urlinfo: web::Query<Info>) -> String {
    println!("username{}, userid{}, age{}, sex{}!", urlinfo.username, urlinfo.userid,  urlinfo.age, urlinfo.sex);
    format!("Welcome {} {}", urlinfo.userid, urlinfo.username)
}

#[post("/formjson")]
async fn formjson(formj: web::Form<Info>) -> Result<HttpResponse> {
    println!("username{}, userid{}, age{}, sex{}!", formj.username, formj.userid,  formj.age, formj.sex);
    // Ok(HttpResponse::Ok().json(
    //     Info{
    //         userid: 114234,
    //         username: String::from("张一鸣"),
    //         age: 35,
    //         sex: String::from("男"),
    //     }
    // ))

    let result = test_save().await;

    Ok(HttpResponse::Ok().json(
        result
    ))
}

#[post("/httpjson")]
async fn httpjson() -> HttpResponse{

    HttpResponse::Ok().json(
        Info{
            userid: 114234,
            username: String::from("张一鸣"),
            age: 35,
            sex: String::from("男"),
        }
    )

}

#[get("/req/{userid}/{friend}")] // <- define path parameters
async fn indexreq(req: HttpRequest) -> Result<String> {
    let name: String = req.match_info().get("friend").unwrap().parse().unwrap();
    let userid: i32 = req.match_info().query("userid").parse().unwrap();

    Ok(format!("Welcome {}, userid {}!", name, userid))
}

// Responder
impl Responder for Info {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

// Responder
impl Responder for BizActivity {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

#[post("/customres")]
async fn custom() -> impl Responder {
    
    // test_save().await;

    // Info{
    //     userid: 114234,
    //     username: String::from("张一鸣"),
    //     age: 35,
    //     sex: String::from("男"),
    // }

    if let Ok(result) = test_find_all().await{
        HttpResponse::Ok().json( result)
    }else{
        let mut map :HashMap<String,  Option<String>> = HashMap::new();
        map.insert("code".to_string(),  Some("400".to_string()));
        map.insert("data".to_string(), None);
        map.insert("message".to_string(), Some("查询失败".to_string()));
        HttpResponse::Ok().json(map)
    }
}

struct Student{
    s_id : String,
    s_name: String,
    s_birth: String,
    s_sex: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct UserInfo {
    // #[serde(rename(serialize = "persons", deserialize = "persons"))]
    info: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Persons {
    // #[serde(rename(serialize = "persons", deserialize = "persons"))]
    persons: Vec<Person>,
}
 
#[derive(Serialize, Deserialize, Debug)]
struct Person {
    // #[serde(rename(serialize = "name", deserialize = "name"))]
    name: String,
    // #[serde(rename(serialize = "age", deserialize = "age"))]
    age: i32,
}

// async fn my_rust_sqlx_demo() {
//     let pool = sqlx::MySqlPool::builder().
//         max_size(100).
//         min_size(10).
//         connect_timeout(std::time::Duration::from_secs(10)).
//         max_lifetime(std::time::Duration::from_secs(1800)).
//         idle_timeout(std::time::Duration::from_secs(600)).
//         build(&std::env::var("mysql://root:123456@127.0.0.1:3306/students").unwrap()).await?;

//         let sql = "select * from student";
//         let s: Student = sqlx::query_as::<_, User>(sql).fetch_one(&pool).await?;
//         println!("{:?}", s);
// }

// impl CRUDEnable for BizActivity {
//     type IdType = String;
// }

#[macro_use]
extern crate rbatis_macro_driver;

#[crud_enable( id_name:id |  id_type:String |  table_name:biz_activity |  table_columns:id,name,store_id,pc_link,h5_link,pc_banner_img,h5_banner_img,sort,status,remark,create_time,update_time,version,delete_flag )]
#[derive(Serialize, Deserialize, Clone, Debug)]
// #[derive(CRUDEnable,Serialize, Deserialize, Clone, Debug)] 
pub struct BizActivity {
    pub id: Option<String>,
    pub name: Option<String>,
    pub store_id: Option<String>,
    pub pc_link: Option<String>,
    pub h5_link: Option<String>,
    pub pc_banner_img: Option<String>,
    pub h5_banner_img: Option<String>,
    pub sort: Option<String>,
    pub status: Option<i32>,
    pub remark: Option<String>,
    pub create_time: Option<NaiveDateTime>,
    pub update_time: Option<NaiveDateTime>,
    pub version: Option<BigDecimal>,
    pub delete_flag: Option<i32>,
    pub commodity_list: Option<Vec<Commodity>>,
}

#[crud_enable( id_name:id |  id_type:String |  table_name:commodity |  table_columns:id,name,remark,create_time,update_time,version,delete_flag )]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Commodity{
    pub id: Option<String>, 
    pub name: Option<String>,
    pub remark: Option<String>,
    pub create_time: Option<NaiveDateTime>,
    pub update_time: Option<NaiveDateTime>,
    pub version: Option<BigDecimal>,
    pub delete_flag: Option<i32>,
}

impl Responder for Commodity {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

#[crud_enable( id_name:id |  id_type:String |  table_name:activity_commodity |  table_columns:id,activity_id,activity_name,commodity_id,commodity_name,remark,create_time,update_time,version,delete_flag )]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ActivityCommodity{
    pub id: Option<String>, 
    pub activity_id: Option<String>, 
    pub activity_name: Option<String>,
    pub commodity_id: Option<String>, 
    pub commodity_name: Option<String>,
    pub remark: Option<String>,
    pub create_time: Option<NaiveDateTime>,
    pub update_time: Option<NaiveDateTime>,
    pub version: Option<BigDecimal>,
    pub delete_flag: Option<i32>,
}

impl Responder for ActivityCommodity {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

#[crud_enable( id_name:id |  id_type:String |  table_name:store |  table_columns:id,name,remark,adress,create_time,update_time,version,delete_flag )]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct  Store{
    pub id: Option<String>, 
    pub name: Option<String>,
    pub remark: Option<String>,
    pub adress: Option<String>,
    pub create_time: Option<NaiveDateTime>,
    pub update_time: Option<NaiveDateTime>,
    pub version: Option<BigDecimal>,
    pub delete_flag: Option<i32>,
    pub biz_activity_list: Option<Vec<BizActivity>>,
}

impl Responder for Store {
    type Error = Error;
    type Future = Ready<Result<HttpResponse, Error>>;

    fn respond_to(self, _req: &HttpRequest) -> Self::Future {
        let body = serde_json::to_string(&self).unwrap();

        // Create response and set content type
        ready(Ok(HttpResponse::Ok()
            .content_type("application/json")
            .body(body)))
    }
}

async fn init_rbatis() ->Rbatis{
    let rb = Rbatis::new();
    ///连接数据库,自动判断驱动类型"mysql://*","postgres://*","sqlite://*","mssql://*"加载驱动   
    rb.link("mysql://root:123456@localhost:3306/rbatis_test").await.unwrap();
    ///自定义连接池参数。(可选)
    // let mut opt =PoolOptions::new();
    // opt.max_size=100;
    // rb.link_opt("mysql://root:123456@localhost:3306/test",&opt).await.unwrap();

    rb
}

async fn test_save() -> Vec<BizActivity >{

    println!("调用 test_save()");
    
    let rb = init_rbatis().await;

    let tx_id = "1";//事务id号
    rb.begin(tx_id).await.unwrap();
    
    let result: Vec<BizActivity> = rb.list("").await.unwrap();
    println!("result = {:?}", result);

    let activity = BizActivity {
        id: Some("12312".to_string()),
        name: Some("Rbatis".to_string()),
        store_id : Some("1774636".to_string()),
        pc_link: None,
        h5_link: None,
        pc_banner_img: None,
        h5_banner_img: None,
        sort: Some("1".to_string()),
        status: Some(1),
        remark: None,
        create_time: Some(NaiveDateTime::now()),
        update_time: Some(NaiveDateTime::now()),
        version: Some(BigDecimal::from(1)),
        delete_flag: Some(1),
        commodity_list: None,
    };
    let r = rb.save("", &activity).await;
    if r.is_err() {
        println!("{}", r.err().unwrap().to_string());
    }

    rb.commit(tx_id).await.unwrap();

    result
}

async fn test_find_all() -> Result<Vec<BizActivity >>{

    println!("调用 test_save()");
    
    let rb = init_rbatis().await;

    let tx_id = "1";//事务id号
    rb.begin(tx_id).await.unwrap();
    
    // let req = PageRequest::new(1, 2);//分页请求，页码，条数
    // let wraper= rb.new_wrapper()
    //             .eq("delete_flag",1)
    //             .check()
    //             .unwrap();
    // let data: Page<BizActivity> = rb.fetch_page_by_wrapper("", &wraper,  &req).await.unwrap();
    
    let result: Vec<BizActivity> = rb.list("").await.unwrap();
    println!("result = {:?}", result);  

    rb.commit(tx_id).await.unwrap();

    Ok(result)
}

#[sql(rbatis, "select * from biz_activity where id = ?")]
async fn select(rbatis: &Rbatis , tx_id:&str , id: &str) -> BizActivity {}

// #[sql(rbatis, "select c.*  from commodity c inner join activity_commodity ac on c.id = ac. commodity_id where ac.activity_id = ?")]
// async fn query_activity_commodity(rbatis: &Rbatis , tx_id:&str , activity_id: &str) -> Vec<Commodity> {}

#[sql(rbatis, "select c.*  from commodity c inner join activity_commodity ac on c.id = ac. commodity_id where ac.activity_id = ?")]
async fn query_activity_commodity(rbatis: &Rbatis , tx_id:&str , activity_id: String) -> Vec<Commodity> {}

#[sql(rbatis, "select c.*  from commodity c inner join activity_commodity ac on c.id = ac. commodity_id inner join  biz_activity ba on ba.id = ac.activity_id where ac.activity_id = ? and ba.store_id = ?")]
async fn query_store_activity_commodity(rbatis: &Rbatis , tx_id:&str , activity_id: &str, store_id :&str) -> Vec<Commodity> {}

#[sql(rbatis, "select * from store")]
async fn select_store(rbatis: &Rbatis , tx_id:&str) -> Vec<Store> {}

#[sql(rbatis, "select * from biz_activity where store_id = ?")]
async fn select_biz_activity_by_store_id(rbatis: &Rbatis , tx_id:&str , store_id: String) -> Vec<BizActivity> {}

async fn update_store() -> HashMap<String, Option<String>>{

    let rb = init_rbatis().await;

    let tx_id = "4";//事务id号
    rb.begin(tx_id).await.unwrap();
    
    let w = rb.new_wrapper().eq("id", "1774639").check().unwrap();
    let store = Store{
        id: Some("1774639".to_string()),
        name: Some("底特律店".to_string()),
        remark: Some("dd".to_string()),
        adress: Some("美国底特律".to_string()),
        create_time: Some(NaiveDateTime::now()),
        update_time: Some(NaiveDateTime::now()),
        version: Some(BigDecimal::from(9)),
        delete_flag: Some(9),
        biz_activity_list: None,
    };

    rb.update_by_wrapper("", &store, &w, true).await.unwrap();

    let mut result  :HashMap<String,  Option<String>> = HashMap::new();
    result .insert("code".to_string(),  Some("200".to_string()));
    result .insert("data".to_string(), None);
    result .insert("message".to_string(), Some("更新成功".to_string()));
    println!("result = {:?}", result);

    rb.commit(tx_id).await.unwrap();

    result
}

async fn delete_store() -> HashMap<String, Option<String>>{

    let rb = init_rbatis().await;

    let tx_id = "5";//事务id号
    rb.begin(tx_id).await.unwrap();

    rb.remove_by_id::<Store>("", &"1774639".to_string()).await;

    let mut result  :HashMap<String,  Option<String>> = HashMap::new();
    result .insert("code".to_string(),  Some("200".to_string()));
    result .insert("data".to_string(), None);
    result .insert("message".to_string(), Some("删除成功".to_string()));
    println!("result = {:?}", result);

    rb.commit(tx_id).await.unwrap();

    result
}

async fn wrapper_query() -> Option<BizActivity>{

    let rb = init_rbatis().await;

    let tx_id = "6";//事务id号
    rb.begin(tx_id).await.unwrap();

    let w = rb.new_wrapper()
            // .eq("id", 1)                    //sql:  id = 1
            // .and()                          //sql:  and 
            // .ne("id", "1")                    //sql:  id <> 1
            // .r#in("id", &[1, 2, 3])     //sql:  id in (1,2,3)
            .not_in("id", &["1", "178", "221", "222", "223"])       //sql:  id not in (1,2,3)
            .like("name", "Rbatis")                //sql:  name like 1
            // .or()                           //sql:  or
            // .not_like("name", "asdf")       //sql:  name not like 'asdf'
            // .between("create_time", "2020-01-01 00:00:00", "2020-12-12 00:00:00")//sql:  create_time between '2020-01-01 00:00:00' and '2020-01-01 00:00:00'
            // .group_by(&["id"])              //sql:  group by id
            .order_by(true, &["create_time"])//sql:  order by id,name
            .check().unwrap();
    let r: Result<Option<BizActivity>, rbatis_error> = rb.fetch_by_wrapper("", &w).await;

    rb.commit(tx_id).await.unwrap();

    match r{
        Ok(result) =>{
            result
        },
        Err(e) =>{
            // let v_list :Vec<BizActivity> = Vec::new();
            // v_list
            
            None
        }
    }
}

#[derive(Serialize, Deserialize)]
struct QueryActivity{
    name: String,
    store_id: String,
    sort: String,
    status: String,
    start_create_time: String,
    end_create_time: String,
    version: String,
    delete_flag: String,
    page_size: u64,
    page_no: u64
}

// async fn wrapper_query_all(qa: &web::Form<QueryActivity>) -> Page<BizActivity>{

//     let rb = init_rbatis().await;

//     let tx_id = "7";//事务id号
//     rb.begin(tx_id).await.unwrap();

//     let req = PageRequest::new(qa.page_no, qa.page_size);//分页请求，页码，条数
//     let mut wraper = rb.new_wrapper();

//     if qa.name != ""{
//         wraper.like("name", qa.name);
//     }

//     if qa.store_id != ""{
//        wraper.eq("store_id", qa.store_id);
//     }

//     if qa.sort != ""{
//         wraper.eq("sort", qa.sort);
//     }

//     if qa.status != ""{
//         wraper.eq("status", qa.status);
//     }

//     if qa.start_create_time != ""{
//         wraper.ge("create_time", qa.start_create_time);
//     }

//     if qa.end_create_time != ""{
//         wraper.le("create_time", qa.end_create_time);
//     }

//     if qa.version != ""{
//         wraper.eq("version", qa.version);
//     }

//     if qa.delete_flag != ""{
//         wraper.eq("delete_flag", qa.delete_flag);
//     }

//     let data: Page<BizActivity> = rb.fetch_page_by_wrapper("", &wraper,  &req).await.unwrap();

//     rb.commit(tx_id).await.unwrap();

//     return data
// }

#[post("/page")]
async fn query_page(qa: web::Form<QueryActivity>) -> Result<HttpResponse> {
    
    let rb = init_rbatis().await;

    let tx_id = "7";//事务id号
    rb.begin(tx_id).await.unwrap();

    let req = PageRequest::new(qa.page_no, qa.page_size);//分页请求，页码，条数
    let mut wraper = rb.new_wrapper();

    if qa.name != ""{
        wraper.like("name", &qa.name);
    }

    if qa.store_id != ""{
       wraper.eq("store_id", &qa.store_id);
    }

    if qa.sort != ""{
        wraper.eq("sort", &qa.sort);
    }

    if qa.status != ""{
        wraper.eq("status", &qa.status);
    }

    if qa.start_create_time != ""{
        wraper.ge("create_time", &qa.start_create_time);
    }

    if qa.end_create_time != ""{
        wraper.le("create_time", &qa.end_create_time);
    }

    if qa.version != ""{
        wraper.eq("version", &qa.version);
    }

    if qa.delete_flag != ""{
        wraper.eq("delete_flag", &qa.delete_flag);
    }

    let data: Page<BizActivity> = rb.fetch_page_by_wrapper("", &wraper,  &req).await.unwrap();

    rb.commit(tx_id).await.unwrap();
    // let v = wrapper_query_all(&qa).await;

    Ok(HttpResponse::Ok().json(
        data
    ))
}

// fn my_mysql_async(){
//     let pool = mysql_async::Pool::new(database_url);
//     let conn = pool.get_conn().await?;
// }

#[post("/analysis")]
async fn analysis(formj: web::Form<UserInfo>) -> Result<HttpResponse> {
    println!("persons{:?},", formj.info);
    
    let v: Persons = serde_json::from_str(&formj.info)?;

    Ok(HttpResponse::Ok().json(
        v
    ))
}

#[post("/wrapper")]
async fn r_wrapper() -> Result<HttpResponse> {
    
    let result = wrapper_query().await;

    if let Some(t) = result{
        Ok(HttpResponse::Ok().json(
            t
        ))
    }else{
        let mut map  :HashMap<String,  Option<String>> = HashMap::new();
        map.insert("code".to_string(),  Some("200".to_string()));
        map.insert("data".to_string(), None);
        map.insert("message".to_string(), Some("查不到数据".to_string()));
        Ok(HttpResponse::Ok().json(
            map
        ))
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {

    // let dsn :&str = "mysql://root:123456@127.0.0.1:3306/test";

    // my_rust_sqlx_demo();

    let json_str = r#"{
        "persons" : [
            {
                "name" : "Joe",
                "age" : 12
            }
        ]
    }"#;
    let v: Persons = serde_json::from_str(&json_str)?;
    println!("{:?}", v);
    let json_str = serde_json::to_string(&v)?;
    println!("{}", json_str);
    let json_str = serde_json::to_string_pretty(&v)?;
    println!("{}", json_str);

    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(echo)
            .service(index)
            .service(info)
            .service(form)
            .service(url)
            .service(formjson)
            .service(indexreq)
            .service(custom)
            .route("/hey", web::get().to(manual_hello))
            .service(delete)
            .service(analysis)
            .service(r_wrapper)
            .service(httpjson)
            .service(query_page)
    })
    .bind("0.0.0.0:1117")?
    .run()
    .await
}